namespace Sedodream.Web.ViewHelper.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Web.Mvc;
    using Sedodream.Web.Common.Contact;
    using Sedodream.Web.Common.Exceptions;
    using Sedodream.Web.ViewHelper.Models;

    public class ContactController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        #region Add
public ActionResult AddContactClassic()
{
    AddContactModel addModel = InternalGetInitialAddModel();

    return View(addModel);
}

private AddContactModel InternalGetInitialAddModel()
{
    string maleString = Gender.Male.ToString();
    string femaleString = Gender.Female.ToString();

    IList<SelectListItem> genderRadioButtons = new List<SelectListItem>()
    {
        new SelectListItem { Text = maleString, Value = Gender.Male.ToString() },
        new SelectListItem { Text = femaleString, Value = Gender.Female.ToString() }
    };

    AddContactModel model = new AddContactModel { GenderList = genderRadioButtons };

    return model;
}

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddContactClassic([Bind(Exclude = "Id")]Contact contact)
        {
            if (contact == null) { throw new ArgumentNullException("contact"); }

            AddContactModel addModel = InternalGetInitialAddModel();

            InternalAddContact(contact,addModel);

            return View(addModel);
        }

        public ActionResult AddContactNew()
        {
            AddContactModel addModel = InternalGetInitialAddModel();

            return View(addModel);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddContactNew([Bind(Exclude = "Id")]Contact contact)
        {
            if (contact == null) { throw new ArgumentNullException("contact"); }

            AddContactModel addModel = InternalGetInitialAddModel();

            InternalAddContact(contact,addModel);

            return View(addModel);
        }

        #endregion

        #region View
        public ActionResult ViewContactsClassic()
        {
            IEnumerable<Contact> model = ContactManager.Instance.GetAllContacts();
            return View(model);
        }

        public ActionResult ViewContactsNew()
        {
            IEnumerable<Contact> model = ContactManager.Instance.GetAllContacts();
            return View(model);
        }
        #endregion

        #region Edit
        public ActionResult EditClassic(Guid id)
        {
            return View(ContactManager.Instance.GetContactById(id));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditClassic(Contact contact)
        {
            if (contact == null) { throw new ArgumentNullException("contact"); }
            if (contact.Id.Equals(Guid.Empty)) { throw new ArgumentNullException("contact.Id"); }

            InternalEditContact(contact);
            return View(contact);
        }

        public ActionResult EditNew(Guid id)
        {
            return View(ContactManager.Instance.GetContactById(id));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditNew(Contact contact)
        {
            if (contact == null) { throw new ArgumentNullException("contact"); }
            if (contact.Id.Equals(Guid.Empty)) { throw new ArgumentNullException("contact.Id"); }

            InternalEditContact(contact);
            return View(contact);
        }
        #endregion

        #region Details
        public ActionResult DetailsClassic(Guid id)
        {
            return View(ContactManager.Instance.GetContactById(id));
        }

        public ActionResult DetailsNew(Guid id)
        {
            return View(ContactManager.Instance.GetContactById(id));
        }
        #endregion

        #region Private methods
        private void InternalEditContact(Contact contact)
        {
            if (contact == null) { throw new ArgumentNullException("contact"); }

            ContactManager.Instance.UpdateContact(contact);
            ContactManager.Instance.SaveChanges();
            ViewData["SuccessMessage"] = "The contact was sucessfully updated";
        }
        
        private void InternalAddContact(Contact contact, AddContactModel model)
        {
            if (contact == null) { throw new ArgumentNullException("contact"); }

            try
            {
                ValidateContact(contact);

                if (ModelState.IsValid)
                {
                    ContactManager.Instance.AddContact(contact);
                    ContactManager.Instance.SaveChanges();
                    model.SuccessMessage = "The user was sucessfully added";
                }
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("UnknownError", "An error has occurred");

                // DO NOT DO THIS FOR AN ACTUAL APPLICATION!
                ModelState.AddModelError("Error:", ex.Message);
                model.ErrorMessage += ex.Message;
            }
        }

        private void ValidateContact(Contact contact)
        {
            if (contact == null) { throw new ArgumentNullException("contact"); }

            try
            {
                ContactManager.Instance.ValidateContact(contact);
            }
            catch (ValidationException vex)
            {
                foreach (KeyValuePair<string, string> error in vex.ValidationErrors)
                {
                    ModelState.AddModelError(error.Key, error.Value);
                }
            }
        }
        #endregion
    }
}
